package cv.gzd.robot.socket;


import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import cv.gzd.robot.pojo.Dev;
import cv.gzd.robot.pojo.po.Message;
import cv.gzd.robot.pojo.po.RobotState;
import cv.gzd.robot.pojo.po.StateCode;
import cv.gzd.robot.service.DevService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;

import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: Jun
 * @Date: 2018/8/21 14:53
 */
@Component
public class SystemWebSocketHandler implements WebSocketHandler {
    /**
     * 保存HttpSession与WebSocketSession的映射关系
     */
    public static final Map<Integer, WebSocketSession> DEV_SOCKET_SESSION_MAP;

    private String walkState;

    @Autowired
    DevService devService;

    static {
        DEV_SOCKET_SESSION_MAP = new ConcurrentHashMap<Integer, WebSocketSession>();
    }

    private static int i;

    /**
     * 建立连接后触发的回调
     * 建立连接后，把设备集写入WebSocketSession
     *
     * @param webSocketSession
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
        final Integer rid = (Integer) webSocketSession.getAttributes().get("rid");
        final Dev dev = devService.selectDevByRiv(rid);
        if (DEV_SOCKET_SESSION_MAP.get(rid) == null) {
            DEV_SOCKET_SESSION_MAP.put(rid, webSocketSession);

            System.err.println("设备" + dev.getRid() + ":" + dev.getRobotname() + "已经连接上");
            //设备连接后的处理

//            //模拟发送机器人的状态信息
//            //此方法会导致线程阻塞
//            RobotState robot = new RobotState();
//            robot.setRobotID(dev.getRid());
//            robot.setPower((int) (Math.random() * 100));
//            for (int i = 0; i <= 100; i+=10) {
//                Message msg = new Message();
//                robot.setPower(100 - i);
//                robot.setSpeed(Math.random() * 50);
//                msg.setDate(new Date());
//                msg.setRobotState(robot);
//                msg.setMsgto(rid);
//                sendMessageToDev(rid, new TextMessage(new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create().toJson(msg)));
//                System.err.println("服务器发送消息:" + msg);
//                Thread.sleep(2000);
//            }

        }
    }

    /**
     * 收到消息时触发的回调
     *
     * @param webSocketSession
     * @param webSocketMessage
     * @throws Exception
     */
    @Override
    public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
//        System.out.println("");
        if (webSocketMessage.getPayloadLength() == 0) {
            return;
        }
        Message msg = new Gson().fromJson(webSocketMessage.getPayload().toString(), Message.class);
//        获取前端的操作信息
        RobotState robot = msg.getRobotState();
        System.out.println("接受来自设备" + robot.getRobotID() + "的信息！");
        switch (robot.getMoveCode()) {
            case 9001:
                walkState = StateCode.FORWARD.getWard();
                break;
            case 9002:
                walkState = StateCode.LEFT.getWard();
                break;
            case 9003:
                walkState = StateCode.RIGHT.getWard();
                break;
            case 9004:
                walkState = StateCode.BACKWARD.getWard();
                break;
            case 9005:
                walkState = StateCode.STOP.getWard();
                break;
            default:
                walkState = "未行动";
                break;
        }
        System.err.println("机器人：" + robot.getRobotID() + ",行动方向:" + walkState);
        //以下操作用于转发信息给机器人

        //模拟发送机器人的状态信息
        //此方法会导致线程阻塞
        robot.setRobotID(robot.getRobotID());
        robot.setPower((int) (Math.random() * 100));
        msg = new Message();
        robot.setPower(100 - i);
        robot.setSpeed(Math.random() * 50);
        msg.setDate(new Date());
        msg.setRobotState(robot);
        msg.setMsgto(robot.getRobotID());
        sendMessageToDev(robot.getRobotID(), new TextMessage(new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create().toJson(msg)));
        System.err.println("服务器发送消息:" + msg);
        i++ ;

    }


    /**
     * 传输消息出错时触发的回调
     *
     * @param webSocketSession
     * @param throwable
     * @throws Exception
     */
    @Override
    public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
        if (webSocketSession.isOpen()) {
            webSocketSession.close();
        }
        Iterator<Map.Entry<Integer, WebSocketSession>> it = DEV_SOCKET_SESSION_MAP.entrySet().iterator();
//        移除当前抛出的异常设备socket会话
        while (it.hasNext()) {
            Map.Entry<Integer, WebSocketSession> next = it.next();
            if (next.getValue().getId().equals(webSocketSession.getId())) {
                Dev dev = devService.selectDevByRiv(next.getKey());
                DEV_SOCKET_SESSION_MAP.remove(next.getKey());
                System.err.println("Socket连接移除:设备" + next.getKey() + ":" + dev.getRobotname());

//                Message msg=new Message();
                //消息处理
            }
        }
    }

    /**
     * 断开连接后触发的回调
     *
     * @param webSocketSession
     * @param closeStatus
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
        Iterator<Map.Entry<Integer, WebSocketSession>> it = DEV_SOCKET_SESSION_MAP.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<Integer, WebSocketSession> next = it.next();
            if (next.getValue().getId().equals(webSocketSession.getId())) {
                Dev dev = devService.selectDevByRiv(next.getKey());
                DEV_SOCKET_SESSION_MAP.remove(next.getKey());
                System.err.println("Socket连接移除:设备" + next.getKey() + ":" + dev.getRobotname());
//                Message msg = new Message();
                //消息处理
            }
        }
    }

    /**
     * 是否处理分片消息
     *
     * @return
     */
    @Override
    public boolean supportsPartialMessages() {
        return false;
    }


    /**
     * 向指定的用户发信息
     *
     * @param rid
     * @param message
     * @throws IOException
     */
    public void sendMessageToDev(Integer rid, TextMessage message) throws IOException {
        WebSocketSession socketSession = DEV_SOCKET_SESSION_MAP.get(rid);
        if (socketSession != null && socketSession.isOpen()) {
            socketSession.sendMessage(message);
            System.out.println("消息已发送");
        }
    }


//    public void sendMessageToDev(Integer rid, robotStateThread t) throws IOException {
//        WebSocketSession socketSession = DEV_SOCKET_SESSION_MAP.get(rid);
//        if (socketSession != null && socketSession.isOpen()) {
//            Message msg = t.getMsg();
//            TextMessage message = new TextMessage(new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create().toJson(msg));
//            socketSession.sendMessage(message);
//            System.out.println("消息已发送");
//        }
//    }
}